package jp.co.worksap.recruiting;

import java.util.NoSuchElementException;

/*
 * In this program, I used a static list to keep all of the queues, each queue represented by its
 * tail node and its size, so we can peek the head node by calculate.
 * 
 * @author chenmo
 */



public class ExamImmutableQueueImpl<E> implements ExamImmutableQueue<E> {

	private Node<E> tail;
	private int size;

	public ExamImmutableQueueImpl() {
		tail = null;
		size = 0;
	}

	public ExamImmutableQueueImpl(Node<E> tail, int size) {
		this.tail = tail;
		this.size = size;
	}

	@Override
	public ExamImmutableQueue<E> enqueue(E e) {

		if (e == null)
			throw new IllegalArgumentException();
		Node<E> node = new Node<E>(e, tail);
		return new ExamImmutableQueueImpl<E>(node, size + 1);
	}

	@Override
	public ExamImmutableQueue<E> dequeue() {
		if (this.tail == null) {
			throw new NoSuchElementException();
		} else {
			return new ExamImmutableQueueImpl<E>(tail, size - 1);
		}
	}

	@Override
	public E peek() {
		if (tail == null) {
			throw new NoSuchElementException();
		} else {
			return tail.getHeadNode(size, tail).e;
		}
	}

	@Override
	public int size() {
		return size;
	}
	
	/*
	 * build a list,each node has a pointer to its previous node
	 */
	public static class Node<E> {
		private E e;
		private Node<E> pre;

		private Node(E e, Node<E> pre) {
			this.e = e;
			this.pre = pre;
		}

		/*
		 * Calculate the head node.
		 */
		private Node<E> getHeadNode(int size, Node<E> node) {
			if (size == 1) {
				return this;
			} else {
				for (int i = 0; i < size; i++) {
					node = node.pre;
				}
				return node;
			}

		}

	}

	public static void main(String[] args) {

	}

}